package com.example.atomic;

import sun.misc.Unsafe;
import sun.reflect.misc.FieldUtil;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

public class UnsafeTest {
    private static Unsafe unsafe;

    public static void main(String[] args) throws NoSuchFieldException {
        // 获取类实例中变量的偏移量
        long valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
        // 基于偏移量对值进行操作
        //        unsafe.compareAndSwapInt(this, valueOffset, expect, update);
        // 获得给定对象偏移量上的int值
//        public native int getInt(Object o, long offset);
        int anInt = unsafe.getInt(1L);
        // 设置给定对象偏移量上的int值
//        public native void putInt(Object o, long offset, int x);
        unsafe.putInt(1L, 10);
        // 获得字段在对象中的偏移量
//        public native long objectFieldOffset(Field f);
        unsafe.objectFieldOffset(FieldUtil.getField(UnsafeTest.class, "getUnsafe"));
        // 设置给定对象的int值，使用volatile语义
//        public native void putIntVolatile(Object o, long offset, int x);
        // 获得给定对象对象的int值，使用volatile语义
//        public native int getIntVolatile(Object o, long offset);
        // 和putIntVolatile()一样，但是它要求被操作字段就是volatile类型的
//        public native void putOrderedInt(Object o, long offset, int x);
    }

    public static Unsafe getUnsafe() {
        if (unsafe == null) {
            try {
                // 通过反射得到unsafe对应的Field对象
                Field field = Unsafe.class.getDeclaredField("theUnsafe");
                // 设置该Field为可访问
                field.setAccessible(true);
                // 通过Field得到该Field对应的具体对象，传入null是因为该Field为static的
                unsafe = (Unsafe) field.get(null);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return unsafe;
    }
}
